/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xenon3d.scene;

import javax.media.opengl.GL2;
import xenon3d.vector.Color3f;

/**
 * The ColoringAttributes object defines attributes used in color selection and
 * shading model. The shading model is handled by using the constant FLAT_SHADING
 * in the appropriate capability methods. By default, shading is set to smooth
 * shading. Set the capability flag FLAT_SHADING to switch to flat shading.
 * 
 * @author Volker Everts
 * @version 0.1 - 04.09.08: Created
 */
public class ColoringAttributes extends Attributes {
    
    // <editor-fold defaultstate="collapsed" desc=" Static Attributes ">
    
    /** The default ColoringAttributes object. */
    static final ColoringAttributes DEFAULT = new ColoringAttributes();
    
    /** The last active ColoringAttributes. */
    static ColoringAttributes last = DEFAULT;

    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc=" Public Enumerations ">
    
    /**
     * The ShadeModel enumeration.
     */
    public static enum ShadeModel {
        
        /** The smooth or gourand shading model. */
        Smooth (GL2.GL_FLAT),
        
        /** The flat shading model. */
        Flat (GL2.GL_SMOOTH);
        
        /** The OpenGL value of the shading flag. */
        int value;
        
        /**
         * Creates a new ShadeModel.
         * @param value the internal OpenGL value
         */
        ShadeModel(int value) {
            this.value = value;
        }
        
    } // end enum ShadeModel

    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc=" Private Fields ">
    
    /** The color attribute. */
    private Color3f color;
    
    /** The shade model attribute. */
    private ShadeModel shadeModel = ShadeModel.Smooth;
    
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc=" Initialization ">
    
    /**
     * Creates a new ColoringAtributes object with default settings. The default
     * settings are:<p>
     * <ul>
     * <li>color: white</li>
     * <li>shade model: smooth shading</li>
     * </ul>
     */
    public ColoringAttributes() {
        this(Color3f.WHITE, ShadeModel.Smooth);
    }
    
    /**
     * Creates a new ColoringAttributes object with the specified color and
     * shade model.
     * @param color the color attribute
     * @param shadeModel the shade model attribute
     */
    public ColoringAttributes(Color3f color, ShadeModel shadeModel) {
        if (color == null) color = Color3f.BLACK;
        if (shadeModel == null) shadeModel = ShadeModel.Smooth; 
        this.color = color;
        this.shadeModel = shadeModel;
    }

    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc=" Public Properties ">
    
    /**
     * Returns the color attribute.
     * @return the color attribute
     */
    public final Color3f getColor() {
        return color;
    }
    
    /**
     * Sets the attribute color.
     * @param color the attribute color
     */
    public final void setColor(Color3f color) {
        checkCapability(Capability.AllowColoringAttributesWrite);
        if (color == null) throw new IllegalArgumentException();
        this.color = color;
    }
    
    /**
     * Returns the shade model for this appearance.
     * @return the shade model
     */
    public final ShadeModel getShadeModel() {
        return shadeModel;
    }
    
    /**
     * Sets the shade model for this appearance.
     * @param model the shading mode
     */
    public final void setShadeModel(ShadeModel model) {
        checkCapability(Capability.AllowColoringAttributesWrite);
        if (model == null) throw new IllegalArgumentException();
        shadeModel = model;
    }
    
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc=" Package Private Methods (OpenGL) ">
    
    @Override
    void apply(GL2 gl) {
        if (this == last) return;
        if (color != last.color) gl.glColor3f(color.r, color.g, color.b);
        if (shadeModel != last.shadeModel) gl.glShadeModel(shadeModel.value);
        last = this;
    }
    
    // </editor-fold>
    
} // end class ColoringAttributes